package org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyTableEndpoint;
import org.wu.framework.lazy.orm.core.persistence.util.LazySQLUtil;
import org.wu.framework.lazy.orm.core.source.adapter.SourceFactory;
import org.wu.framework.lazy.orm.database.lambda.domain.PersistenceRepository;
import org.wu.framework.lazy.orm.database.lambda.stream.LambdaTableType;
import org.wu.framework.lazy.orm.database.lambda.stream.condition.part.SqlPart;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.method.interceptor.tenant.LazyTenantLineHandler;

import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * 租户ID 列（ TenantId 行级 ）
 */
@Slf4j
public class TenantIdSqlInterceptor extends AbstractSqlInterceptor {

    private final LazyTenantLineHandler lazyTenantLineHandler;

    public TenantIdSqlInterceptor(LazyTenantLineHandler lazyTenantLineHandler) {
        this.lazyTenantLineHandler = lazyTenantLineHandler;
    }

    /**
     * before insertWithSet sql解析拦截
     *
     * @param persistenceRepository 预执行SQL需要的属性
     */
    @Override
    protected void beforeInsertInterceptor(PersistenceRepository persistenceRepository) {
        List<String> tableList = tableInterceptor(persistenceRepository);
        for (String table : tableList) {
            boolean ignoreTable = lazyTenantLineHandler.ignoreTable(table);
            if (ignoreTable) {
                return;
            }
        }

        String tenantIdColumn = lazyTenantLineHandler.tenantIdColumn();
        String tenantId = lazyTenantLineHandler.getTenantId();


        ConcurrentMap<Class<?>, LazyTableEndpoint<?>> tableCache = SourceFactory.getClassTableCache();

        List<LazyTableEndpoint<?>> currentLazyTableEndpointList = tableCache.values().stream().toList();
        SqlPart sqlPart = persistenceRepository.getSqlPart();
        // 含有租户ID的表
        long count = currentLazyTableEndpointList
                .stream()
                .filter(lazyTableEndpoint -> tableList.contains(lazyTableEndpoint.getTableName()))
                .filter(lazyTableEndpoint -> lazyTableEndpoint
                        .getLazyTableFieldEndpointList()
                        .stream()
                        .anyMatch(lazyTableFieldEndpoint -> tenantIdColumn.equals(lazyTableFieldEndpoint.getColumnName()
                                )
                        )
                )
                .count();

        // 添加数据隔离字段
        if (count > 0) {
            List<HashMap<String, Object>> newInsert = sqlPart.getInsert().stream().peek(stringObjectHashMap -> {
                stringObjectHashMap.put(tenantIdColumn, LazySQLUtil.valueToSqlValue(tenantId));
            }).collect(Collectors.toList());
            sqlPart.setInsert(newInsert);
            PersistenceRepository newPersistenceRepository = sqlPart.persistenceRepository();
            String newSql = newPersistenceRepository.getBeforeQueryString();
            persistenceRepository.setQueryString(newSql);
        }


    }

    /**
     * before delete sql解析拦截
     *
     * @param persistenceRepository 预执行SQL需要的属性
     */
    @Override
    protected void beforeDeleteInterceptor(PersistenceRepository persistenceRepository) {
        intercept(persistenceRepository);

    }

    /**
     * before update sql解析拦截
     *
     * @param persistenceRepository 预执行SQL需要的属性
     */
    @Override
    protected void beforeUpdateInterceptor(PersistenceRepository persistenceRepository) {
        intercept(persistenceRepository);
    }

    private void intercept(PersistenceRepository persistenceRepository) {
        List<String> tableList = tableInterceptor(persistenceRepository);
        for (String table : tableList) {
            boolean ignoreTable = lazyTenantLineHandler.ignoreTable(table);
            if (ignoreTable) {
                return;
            }
        }

        String tenantIdColumn = lazyTenantLineHandler.tenantIdColumn();
        String tenantId = lazyTenantLineHandler.getTenantId();


        ConcurrentMap<Class<?>, LazyTableEndpoint<?>> tableCache = SourceFactory.getClassTableCache();

        List<LazyTableEndpoint<?>> currentLazyTableEndpointList = tableCache.values().stream().toList();
        SqlPart sqlPart = persistenceRepository.getSqlPart();
        if (ObjectUtils.isEmpty(sqlPart)) {
            log.warn("sqlPart is empty with : {}", persistenceRepository);
            return;
        }
        // 含有租户ID的表
        List<LazyTableEndpoint<?>> lazyTableEndpointList = currentLazyTableEndpointList
                .stream()
                .filter(lazyTableEndpoint -> tableList.contains(lazyTableEndpoint.getTableName()))
                .filter(lazyTableEndpoint -> lazyTableEndpoint.getLazyTableFieldEndpointList().stream().anyMatch(lazyTableFieldEndpoint -> tenantIdColumn.equals(lazyTableFieldEndpoint.getColumnName())))
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(LazyTableEndpoint::getTableName))), ArrayList::new));

        for (LazyTableEndpoint<?> lazyTableEndpoint : lazyTableEndpointList) {
            // 表名+字段名
            sqlPart.put(lazyTableEndpoint.getTableName() + "." + tenantIdColumn, "=", tenantId);
        }


        PersistenceRepository newPersistenceRepository = sqlPart.persistenceRepository();
        String newSql = newPersistenceRepository.getBeforeQueryString();
        persistenceRepository.setQueryString(newSql);
    }

    /**
     * before select sql解析拦截
     *
     * @param persistenceRepository 预执行SQL需要的属性
     */
    @Override
    protected void beforeSelectInterceptor(PersistenceRepository persistenceRepository) {
        intercept(persistenceRepository);
    }

    /**
     * 支持
     *
     * @param persistenceRepository 预执行SQL需要的属性
     * @return 布尔类型
     */
    @Override
    public boolean support(PersistenceRepository persistenceRepository) {
        // 支持增删改查
        if (ObjectUtils.isEmpty(persistenceRepository)) return false;
        LambdaTableType executionType = persistenceRepository.getExecutionType();

        return executionType.equals(LambdaTableType.INSERT)
                || executionType.equals(LambdaTableType.UPSERT)
                || executionType.equals(LambdaTableType.DELETE)
                || executionType.equals(LambdaTableType.UPDATE)
                || executionType.equals(LambdaTableType.SELECT)
                || executionType.equals(LambdaTableType.BATCH);
    }
}

class DefaultLazyTenantLineHandler implements LazyTenantLineHandler {

    /**
     * 获取租户 ID 值表达式，只支持单个 ID 值
     * <p>
     *
     * @return 租户 ID 值表达式
     */
    @Override
    public String getTenantId() {
        // 上下文获取租户ID

        return null;
    }
}
